import { Icon } from '@iconify/vue'
import {
  Button,
  Card,
  Col,
  Form,
  FormItem,
  Input,
  message,
  Row,
  Space,
  Spin,
  Textarea
} from 'ant-design-vue'
import { defineComponent, onMounted, ref } from 'vue'

import { cacheApi } from '@/apis'
import { ProTable } from '@/components'
import { TableOptions, useTableRef } from '@/hooks'

export default defineComponent({
  name: 'CacheListView',
  setup() {
    const nowCacheName = ref('')
    const namesTableConfig = ref({
      showOverflow: true,
      highlightCurrentRow: true,
      columns: [
        {
          type: 'seq',
          title: '序号',
          width: 50
        },
        {
          field: 'cacheName',
          title: '缓存名称',
          align: 'center'
        },
        {
          field: 'remark',
          title: '备注',
          align: 'center'
        },
        {
          title: '操作',
          width: 50,
          align: 'center',
          slots: {
            default: 'operation'
          }
        }
      ],
      onCurrentChange() {
        getCacheKeys()
      }
    } as TableOptions)
    const keysTableConfig = ref({
      showOverflow: true,
      highlightCurrentRow: true,
      columns: [
        {
          type: 'seq',
          title: '序号',
          width: 50
        },
        {
          field: 'cacheKey',
          title: '缓存键名',
          align: 'center'
        },
        {
          title: '操作',
          width: 50,
          align: 'center',
          slots: {
            default: 'operation'
          }
        }
      ],
      onCurrentChange() {
        getCacheValue()
      }
    } as TableOptions)
    const cacheValue = ref({
      cacheName: '',
      cacheKey: '',
      cacheValue: ''
    })
    const valueLoading = ref(false)

    const { tableRef: namesTableRef, ...namesTableRefRestHook } =
      useTableRef(namesTableConfig)
    const { tableRef: keysTableRef, ...keysTableRefRestHook } =
      useTableRef(keysTableConfig)

    async function getCacheNames() {
      namesTableRefRestHook.showLoading()

      const data = await cacheApi.getCacheNames()
      namesTableConfig.value.data = data

      namesTableRefRestHook.hideLoading()
    }

    async function getCacheKeys() {
      const current = namesTableRef.value.getCurrentRecord()

      if (!current) return

      keysTableRefRestHook.showLoading()

      const keys = await cacheApi.getCacheKeys(current.cacheName)

      keysTableConfig.value.data = keys.map(v => ({
        cacheKey: v.replace(`${current.cacheName}:`, '')
      }))
      nowCacheName.value = current.cacheName

      keysTableRefRestHook.hideLoading()
    }

    function clearCacheKeys() {
      keysTableConfig.value.data = []
    }

    async function getCacheValue() {
      const nameCurrent = namesTableRef.value.getCurrentRecord()
      const keyCurrent = keysTableRef.value.getCurrentRecord()

      if (!nameCurrent) return
      if (!keyCurrent) return

      valueLoading.value = true

      const data = await cacheApi.getCacheValue(
        `${nameCurrent.cacheName}:${keyCurrent.cacheKey}`
      )
      cacheValue.value = {
        ...data,
        cacheValue: JSON.stringify(data.cacheValue)
      }

      valueLoading.value = false
    }

    function clearCacheValue() {
      cacheValue.value.cacheKey = ''
      cacheValue.value.cacheName = ''
      cacheValue.value.cacheValue = ''
    }

    async function handleRefreshCacheNames() {
      await getCacheNames()
      clearCacheKeys()
      clearCacheValue()
      message.success('刷新缓存列表成功', 1)
    }

    async function handleRefreshCacheKeys() {
      // 缓存列表没选中项时，不执行刷新
      if (!namesTableRef.value.getCurrentRecord()) {
        message.warn('请先选中缓存列表项', 1)
        return
      }

      await getCacheKeys()
      clearCacheValue()
      message.success('刷新键名列表成功', 1)
    }

    async function handleDeleteCacheName(cacheName: string) {
      namesTableRefRestHook.showLoading()

      await cacheApi.clearCacheName(cacheName)

      namesTableRefRestHook.hideLoading()
      message.success('清除缓存名称成功', 1)

      if (nowCacheName.value && nowCacheName.value === cacheName) {
        keysTableConfig.value.data = []
      }
    }

    async function handleDeleteCacheKey(cacheKey: string) {
      const currentName = namesTableRef.value.getCurrentRecord()

      const key = `${currentName.cacheName}:${cacheKey}`

      keysTableRefRestHook.showLoading()

      await cacheApi.clearCacheKey(key)

      keysTableRefRestHook.hideLoading()
      message.success('清除缓存键名成功', 1)
      getCacheKeys()
      clearCacheValue()
    }

    onMounted(() => {
      getCacheNames()
    })

    return {
      namesTableRef,
      namesTableConfig,
      keysTableRef,
      keysTableConfig,
      cacheValue,
      valueLoading,
      handleRefreshCacheNames,
      handleRefreshCacheKeys,
      handleDeleteCacheName,
      handleDeleteCacheKey
    }
  },
  render() {
    return (
      <div>
        <Row gutter={15}>
          <Col span={8}>
            <Card
              title={'缓存列表'}
              bodyStyle={{ height: 'calc(100vh - 185px)' }}
              v-slots={{
                extra: () => (
                  <Button
                    type={'link'}
                    icon={<Icon icon={'ant-design:reload-outlined'} />}
                    style={{ width: 'auto', height: 0, padding: 0 }}
                    onClick={this.handleRefreshCacheNames}
                  ></Button>
                )
              }}
            >
              <ProTable
                ref="namesTableRef"
                v-slots={{
                  operation: ({ row }) => (
                    <Space size={'small'}>
                      <Button
                        type={'link'}
                        size={'small'}
                        icon={<Icon icon={'ant-design:delete-outlined'} />}
                        style={{ width: 'auto', height: 0, padding: 0 }}
                        onClick={e => {
                          e.stopPropagation()
                          this.handleDeleteCacheName(row.cacheName)
                        }}
                      ></Button>
                    </Space>
                  )
                }}
                {...this.namesTableConfig}
              />
            </Card>
          </Col>
          <Col span={8}>
            <Card
              title={'键名列表'}
              bodyStyle={{ height: 'calc(100vh - 185px)' }}
              v-slots={{
                extra: () => (
                  <Button
                    type={'link'}
                    icon={<Icon icon={'ant-design:reload-outlined'} />}
                    style={{ width: 'auto', height: 0, padding: 0 }}
                    onClick={this.handleRefreshCacheKeys}
                  ></Button>
                )
              }}
            >
              <ProTable
                ref="keysTableRef"
                v-slots={{
                  operation: ({ row }) => (
                    <Space size={'small'}>
                      <Button
                        type={'link'}
                        size={'small'}
                        icon={<Icon icon={'ant-design:delete-outlined'} />}
                        style={{ width: 'auto', height: 0, padding: 0 }}
                        onClick={e => {
                          e.stopPropagation()
                          this.handleDeleteCacheKey(row.cacheKey)
                        }}
                      ></Button>
                    </Space>
                  )
                }}
                {...this.keysTableConfig}
              />
            </Card>
          </Col>
          <Col span={8}>
            <Card
              title={'缓存内容'}
              bodyStyle={{ height: 'calc(100vh - 185px)' }}
            >
              <Spin spinning={this.valueLoading}>
                <Form layout={'vertical'}>
                  <FormItem label={'缓存名称'}>
                    <Input v-model:value={this.cacheValue.cacheName} readonly />
                  </FormItem>
                  <FormItem label={'缓存键名'}>
                    <Input v-model:value={this.cacheValue.cacheKey} readonly />
                  </FormItem>
                  <FormItem label={'缓存内容'}>
                    <Textarea
                      v-model:value={this.cacheValue.cacheValue}
                      rows={8}
                      readonly
                    />
                  </FormItem>
                </Form>
              </Spin>
            </Card>
          </Col>
        </Row>
      </div>
    )
  }
})
